mipi转lvds芯片GM877C使用参考
1. 用户需求¶
-
Takoyaki需要点LVDS panel,只支持TTL and MIPI 接口。
-
根据需求选用外围器件GM877C做mipi2lvds转换,间接点LVDS panel。
-
用户A需要点的lvds panel为960X1280分辨率。
-
用户B需要点的lvds panel为1920X1080分辨率。
2. 公版状态¶
-
公版mi panel owner之前已经用GM877C点过lvds panel,已经有base code。
-
对应屏参给到用户,用户反馈没有作用。
-
需要进到具体问题分析具体状态。
3. 调试过程¶
-
硬件连接
-
调试过程
-
根据调试过程的经验来看,首先需要请GM877C的芯片抛开主芯片,来点亮lvds panel确定GM芯片和panle电路是OK的。这部分需要硬件在开始设计的时候板子预留GM的I2C接口和外部晶振接口。这步骤是很重要的,是一定要做的,方便梳理清楚问题。
这部分可以请用户找GM的人配合调试,如下是用到的工具,GM调试PC工具可以自动生成参数,通过USB2IIC写入GM芯片点亮LVDS panle。
这里在实际调试过程中有如下注意点:
通过这个工具write之后,可以通过read看是否写的正确?如果不正确,可以通过单独命令w,0xxx,0xxxx,然后单独命令R,0xxx来确认是否写的正确,如果单独命令正确,有可能是I2C速度太快造成写很多不正确,可以手动一条条的单独写,然后再read,看是否正确,这样就用最简单的方法点亮panel。
-
以上步骤点亮panel之后,就大致确认到GM+panel电路正确,LVDS panel 参数大致OK。我们通过GM的工具切换到"MIPI命令",生成命令参数添加到GM8775C_CMD,注意刚开始点的时候,生成测试命令建议打开测试pattern,如下:
-
修改stPanelParam内容,按照panel spec填写。
MI_PANEL_ParamConfig_t stPanelParam = { "GM8775C_960x1280", //const char *pPanelName; ///< PanelName 0, //MI_U8 MI_U8Dither; ///< Diether On?off E_MI_PNL_LINK_MIPI_DSI, //MIPnlLinkType_e eLinkType; ///< Panel LinkType 0, //MI_U8 MI_U8DualPort :1; ///< DualPort on/off 0, //MI_U8 MI_U8SwapPort :1; ///< Swap Port on/off 0, //MI_U8 MI_U8SwapOdd_ML :1; ///< Swap Odd ML 0, //MI_U8 MI_U8SwapEven_ML :1; ///< Swap Even ML 0, //MI_U8 MI_U8SwapOdd_RB :1; ///< Swap Odd RB 0, //MI_U8 MI_U8SwapEven_RB :1; ///< Swap Even RB 0, //MI_U8 MI_U8SwapLVDS_POL :1; ///< Swap LVDS Channel Polairyt 0, //MI_U8 MI_U8SwapLVDS_CH :1; ///< Swap LVDS channel 0, //MI_U8 MI_U8PDP10BIT :1; ///< PDP 10bits on/off 0, //MI_U8 MI_U8LVDS_TI_MODE :1; ///< Ti Mode On/Off 0, //MI_U8 MI_U8DCLKDelay; ///< DCLK Delay 0, //MI_U8 MI_U8InvDCLK :1; ///< CLK Invert 0, //MI_U8 MI_U8InvDE :1; ///< DE Invert 0, //MI_U8 MI_U8InvHSync :1; ///< HSync Invert 0, //MI_U8 MI_U8InvVSync :1; ///< VSync Invert 0, //MI_U8 MI_U8DCKLCurrent; ///< PANEL_DCLK_CURRENT 0, //MI_U8 MI_U8DECurrent; ///< PANEL_DE_CURRENT 0, //MI_U8 MI_U8ODDDataCurrent; ///< PANEL_ODD_DATA_CURRENT 0, //MI_U8 MI_U8EvenDataCurrent; ///< PANEL_EVEN_DATA_CURRENT 0, //u16 u16OnTiming1; ///< time between panel & data while turn on power 0, //u16 u16OnTiming2; ///< time between data & back light while turn on power 0, //u16 u16OffTiming1; ///< time between back light & data while turn off power 0, //u16 u16OffTiming2; ///< time between data & panel while turn off power 20, //u16 u16HSyncWidth; ///< Hsync Width 20, //u16 u16HSyncBackPorch; ///< Hsync back porch 10, //u16 u16VSyncWidth; ///< Vsync width 10, //u16 u16VSyncBackPorch; ///< Vsync back porch 0, //u16 u16HStart; ///< HDe start 0, //u16 u16VStart; ///< VDe start 960, //u16 u16Width; ///< Panel Width 1280, //u16 u16Height; ///< Panel Height 0, //u16 u16MaxHTotal; ///< Max H Total 1020, //u16 u16HTotal; ///< H Total 0, //u16 u16MinHTotal; ///< Min H Total 0, //u16 u16MaxVTotal; ///< Max V Total 1320, //u16 u16VTotal; ///< V Total 0, //u16 u16MinVTotal; ///< Min V Total 0, //u16 u16MaxDCLK; ///< Max DCLK 81, //u16 u16DCLK; ///< DCLK ( Htt * Vtt * Fps) 0, //u16 u16MinDCLK; ///< Min DCLK 0, //u16 u16SpreadSpectrumStep; ///< Step of SSC 0, //u16 u16SpreadSpectrumSpan; ///< Span of SSC 0, //MI_U8 MI_U8DimmingCtl; ///< Dimming Value 0, //MI_U8 MI_U8MaxPWMVal; ///< Max Dimming Value 0, //MI_U8 MI_U8MinPWMVal; ///< Min Dimming Value 0, //MI_U8 MI_U8DeinterMode :1; ///< DeInter Mode E_MI_PNL_ASPECT_RATIO_WIDE, //MIPnlAspectRatio_e ePanelAspectRatio; ///< Aspec Ratio 0, //u16 u16LVDSTxSwapValue; // LVDS Swap Value E_MI_PNL_TI_8BIT_MODE, //MIPnlTiBitMode_e eTiBitMode; // Ti Bit Mode E_MI_PNL_OUTPUT_8BIT_MODE, //MIPnlOutputFormatBitMode_e eOutputFormatBitMode; 0, //MI_U8 MI_U8SwapOdd_RG :1; ///< Swap Odd RG 0, //MI_U8 MI_U8SwapEven_RG :1; ///< Swap Even RG 0, //MI_U8 MI_U8SwapOdd_GB :1; ///< Swap Odd GB 0, //MI_U8 MI_U8SwapEven_GB :1; ///< Swap Even GB 0, //MI_U8 MI_U8DoubleClk :1; ///< Double CLK On/off 0x0, //u32 u32MaxSET; ///< Max Lpll Set 0x0, //u32 u32MinSET; ///< Min Lpll Set E_MI_PNL_CHG_VTOTAL, //MIPnlOutputTimingMode_e eOutTimingMode; ///< Define which panel output timing change mode is used to change VFreq for same panel 0, //MI_U8 MI_U8NoiseDith :1; ///< Noise Dither On/Off (MI_PANEL_ChannelSwapType_e)2, (MI_PANEL_ChannelSwapType_e)4, (MI_PANEL_ChannelSwapType_e)3, (MI_PANEL_ChannelSwapType_e)1, (MI_PANEL_ChannelSwapType_e)0, };
-
修改stMipiDsiConfig,主要修改//HsTrail HsPrpr HsZero ClkHsPrpr ClkHsExit ClkTrail ClkZero ClkHsPost DaHsExit ,按照规格重新算一遍:
注意mipi的chanel swap和p/n swap是否和公版的线序一样是否要做调整?
MI_PANEL_MipiDsiConfig_t stMipiDsiConfig = { //HsTrail HsPrpr HsZero ClkHsPrpr ClkHsExit ClkTrail ClkZero ClkHsPost DaHsExit ContDet 0x05, 0x05, 0x06, 0x07, 0x0D, 0x06, 0x0E, 0x0B, 0x07, 0x00, //Lpx TaGet TaSure TaGo 0x10, 0x1A, 0x18, 0x32, //Hac, Hpw, Hbp, Hfp, Vac, Vpw, Vbp, Vfp, Bllp, Fps 960, 20, 20, 20, 1280, 10, 10, 20, 0, 60, E_MI_PNL_MIPI_DSI_LANE_4, // MIPnlMipiDsiLaneMode_e enLaneNum; E_MI_PNL_MIPI_DSI_RGB888, // MIPnlMipiDsiFormat_e enFormat; E_MI_PNL_MIPI_DSI_SYNC_PULSE, // MIPnlMipiDsiCtrlMode_e enCtrl; GM8775C_CMD, sizeof(GM8775C_CMD), 1, 0x01AF, 0x01B9, 0x80D2, 7, 0,0,0,0,0,1, };
-
如何配置HS定时参数
-
如何配置LP定时参数
-
屏参合入之后,程序运行之前,检查相关寄存器和GPIO是否设置正确,例如用户这块panel,因为用的是ttl的程序点的, 先要/config/riu_w 101e 0xd 0x1000 pin demux设置正确, 然后因为硬件需要把如下gpio设置为高,先要设置如下GPIO,根据用户硬件不同,是不一样的。
echo 4 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio4/direction echo 1 > /sys/class/gpio/gpio4/value echo 19 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio19/direction echo 1 > /sys/class/gpio/gpio19/value echo 10 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio10/direction echo 1 > /sys/class/gpio/gpio10/value
-
运行demo,查看屏幕是否正常。
-
屏幕正常之后,关闭GM的测试PATTERN,去掉GM芯片的外围晶振,再来看是否正常。注意mipi时钟要调正确:
Pixel CLK:像素时钟
MIPI CLK:MIPI时钟
LVDS CLK:LVDS时钟
像素时钟的计算方式为:
Pixel CLK=(H Total * V Total) * FPS
MIPI时钟的计算方式根据MIPI数据输入时所用的通道LANE的数量决定。
即Mipiclock = [ (width+hsync+hfp+hbp) x (height+vsync+vfp+vbp) ] x(bus_width) x fps/ (lane_num)/2。
即mipi 屏的传输时钟频率(CLKN,CLKP)等于(屏幕分辨率宽width+hsync+hfp+hbp)x (屏幕分辨率高height+vsync+vfp+vbp) x(RGB显示数据宽度) x 帧率/ (lane_num)/2。
在这里除以2是因为MIPI时钟的触发方式为双边沿触发。
GM8775C,输出端LVDS像素时钟为:Pixel CLK=(H Total * V Total) * FPS
对于LVDS CLK来说,当输出为单通道的LVDS信号时,LVDS CLK和它的像素时钟相等。当输出为双通道的LVDS信号时,LVDS CLK是它的像素时钟的一半。
-
对于用户960X1280这块panel,实际调试的时候发现屏幕闪,把stPanelParam.u16HStart,stPanelParam.u16VStart设置为0,再来看,画面正常。
-